<template>
  <a-layout class="editor">
    <a-layout-header class="header">
      <a-space class="left" align="center" size="mini">
        <template #split>
          <a-divider direction="vertical" />
        </template>
        <a-button href="/" type="text"> <i class="bi-arrow-left-line pr5" /> 返回 </a-button>
        <h2 class="text-lg w-50">
          <a-typography-paragraph editable v-model:editText="visual.title" style="margin-bottom: 0">
            {{ visual.title }}
          </a-typography-paragraph>
        </h2>
        <span class="text-xs font-light">最后保存于{{ visual.update_time }}</span>
      </a-space>
      <a-space align="center" class="right" size="mini">
        <template #split>
          <a-divider direction="vertical" />
        </template>
        <a-typography-text v-if="isDevMode" size="small" type="text" class="cursor-pointer" @click="viewStructure">
          <i class="bi-eye-line mr-2" />查看结构
        </a-typography-text>
        <a-typography-text size="small" type="text" class="cursor-pointer" @click="importJson">
          <i class="bi-download-cloud-line mr-2" />
          {{ screenId ? "导出" : "导入" }}
        </a-typography-text>
        <a-typography-text size="small" type="text" @click="previewVisual" class="cursor-pointer">
          <i class="bi-reserved-line mr-2" />预览
        </a-typography-text>
        <a-typography-text size="small" type="text" v-debounce @click="saveVisual" class="cursor-pointer">
          <i class="bi-save-line mr-2" />保存
        </a-typography-text>
        <a-typography-text size="small" type="text" v-debounce @click="saveVisual" class="cursor-pointer">
          <i class="bi-share-line mr-2" />分享
        </a-typography-text>
      </a-space>
    </a-layout-header>
    <a-layout class="editor-content">
      <a-layout-sider
        class="layer"
        hide-trigger
        collapsible
        :collapsed="collapsed"
        :collapsed-width="0"
        default-collapsed
      >
        <div class="header">
          <a-button size="mini" long>图层</a-button>
          <a-button type="text" size="mini" long>页面</a-button>
        </div>
        <a-space class="layer-tool">
          <a-button
            :disabled="!currentComponent.key"
            type="text"
            size="small"
            title="上移一层"
            @click="handleSelect('up')"
          >
            <span class="bi-arrow-up-line" />
          </a-button>
          <a-button
            :disabled="!currentComponent.key"
            type="text"
            size="small"
            title="下移一层"
            @click="handleSelect('down')"
          >
            <span class="bi-arrow-down-line" />
          </a-button>
          <a-button
            :disabled="!currentComponent.key"
            type="text"
            size="small"
            title="置顶"
            @click="handleSelect('top')"
          >
            <span class="bi-skip-up-line" />
          </a-button>
          <a-button
            :disabled="!currentComponent.key"
            type="text"
            size="small"
            title="置底"
            @click="handleSelect('bottom')"
          >
            <span class="bi-skip-down-line" />
          </a-button>
        </a-space>
        <VueDraggable
          v-model="componentList"
          class="layer-list"
          item-key="zIndex"
          :animation="200"
          @end="sortComponent"
        >
          <div
            v-for="element in componentList"
            :key="element.key"
            class="layer-item"
            :class="currentComponent.key === element.key ? 'active' : ''"
            :data-key="element.key"
            @click="selectComponent(element)"
            @contextmenu="rightClick($event, element)"
          >
            {{ element.element.title || element.title }}
            <div class="tool">
              <span @click.stop="element.element.hidden = !element.element.hidden">
                <span :class="element.element.hidden ? 'bi-eye-off-line' : 'bi-eye-line'" />
              </span>
              <span @click.stop="element.element.lock = !element.element.lock">
                <span :class="element.element.lock ? 'bi-lock-line' : 'bi-lock-unlock-line'" />
              </span>
            </div>
          </div>
        </VueDraggable>
      </a-layout-sider>
      <a-layout-content id="canvasEditRef" class="layout">
        <canvasEdit ref="canvasEditRef" />
      </a-layout-content>
      <a-layout-sider class="option" id="settings" :width="330">
        <a-space class="option-header">
          <template v-if="currentComponent.key">
            <a-button
              size="small"
              :type="optionComponentValue === 'style' ? 'primary' : 'default'"
              @click="optionComponentValue = 'style'"
            >
              组件样式
            </a-button>
            <a-button
              v-if="currentComponent.data?.dimension"
              size="small"
              :type="optionComponentValue === 'dataSetting' ? 'primary' : 'default'"
              @click="optionComponentValue = 'dataSetting'"
            >
              数据设置
            </a-button>
          </template>
          <template v-else>页面设置</template>
        </a-space>
        <div class="option-option">
          <template v-if="currentComponent.key">
            <template v-if="optionComponentValue === 'style'">
              <a-tabs position="left" default-active-key="1" v-model="optionValue" destroy-on-hide class="pt-1">
                <a-tab-pane key="1" title="公共属性">
                  <global v-bind="currentComponent" />
                </a-tab-pane>
                <a-tab-pane key="2" title="组件配置">
                  <component
                    :is="`${currentComponent.name}-option`"
                    :key="currentComponent.key"
                    :option="currentComponent.option"
                  />
                </a-tab-pane>
                <a-tab-pane v-for="item in currentComponent.optionSet" :key="item.name" :title="item.title">
                  <!--                  {{ item.name }}{{ currentComponent.option }}-->
                  <component
                    :is="item.name"
                    :key="currentComponent.key"
                    :data="currentComponent.data"
                    :option="currentComponent.option"
                  />
                </a-tab-pane>
                <!--                <template v-for="(item, index) in currentComponent.optionSet" :key="item.name">-->
                <!--                  &lt;!&ndash;                  {{ currentComponent.option }}&ndash;&gt;-->
                <!--                 -->
                <!--                </template>-->
              </a-tabs>
            </template>
            <template v-if="optionComponentValue === 'dataSetting'">
              <a-form size="mini" layout="inline" auto-label-width class="overflow-auto h-full">
                <datasetting />
              </a-form>
            </template>
          </template>
          <template v-else-if="groupManager.length > 0">
            <a-space class="p-2" direction="horizontal" wrap>
              <a-button type="outline" size="mini" @click="groupAlign('width')">等宽</a-button>
              <a-button type="outline" size="mini" @click="groupAlign('height')">等高</a-button>
              <a-button type="outline" size="mini" @click="groupAlign('top')">顶部对齐</a-button>
              <a-button type="outline" size="mini" @click="groupAlign('bottom')">底部对齐</a-button>
              <a-button type="outline" size="mini" @click="groupAlign('left')">左对齐</a-button>
              <a-button type="outline" size="mini" @click="groupAlign('right')">右对齐</a-button>
              <a-button type="outline" size="mini" @click="groupAlign('horizontal')">水平居中</a-button>
              <a-button type="outline" size="mini" @click="groupAlign('vertical')">垂直居中</a-button>
              <a-button
                :disabled="groupManager.length < 3"
                type="outline"
                size="mini"
                @click="groupAlign('horizontal-distribution')"
                >横向分布</a-button
              >
              <a-button
                :disabled="groupManager.length < 3"
                type="outline"
                size="mini"
                @click="groupAlign('vertical-distribution')"
                >纵向分布</a-button
              >
            </a-space>
          </template>
          <template v-else>
            <a-form class="p-2" auto-label-width size="mini">
              <a-form-item label="屏幕宽度">
                <xiri-form v-model="commonStyle.width" option="number" />
              </a-form-item>
              <a-form-item label="屏幕高度">
                <xiri-form v-model="commonStyle.height" option="number" />
              </a-form-item>
              <a-form-item label="背景纯色">
                <xiri-form v-model="commonStyle.backgroundColor" option="linearColor" />
              </a-form-item>
              <a-form-item label="背景图片" extra="背景比纯色优先级高">
                <xiri-form v-model="commonStyle.backgroundImage" option="img" />
                <template #label>
                  <div>背景图片</div>
                  <xiri-form v-model="commonStyle.backgroundImage" option="imageChoose" />
                </template>
              </a-form-item>
              <a-form-item v-if="commonStyle.backgroundImage" label="背景位置">
                <a-select v-model="commonStyle.backgroundPosition">
                  <a-option value="center" label="居中">居中</a-option>
                  <a-option value="center top" label="中上">中上</a-option>
                  <a-option value="center bottom" label="中下">中下</a-option>
                </a-select>
              </a-form-item>
              <a-form-item v-if="commonStyle.backgroundImage" label="缩放方式">
                <a-radio-group v-model="commonStyle.backgroundSize" size="small">
                  <a-radio value="cover">填充</a-radio>
                  <a-radio value="contain">适应</a-radio>
                  <a-radio value="100% 100%">拉伸</a-radio>
                </a-radio-group>
              </a-form-item>
              <a-form-item label="主题模式">
                <a-radio-group v-model="commonStyle.theme" size="small" type="button">
                  <a-radio value="dark">深色模式</a-radio>
                  <a-radio value="light">浅色模式</a-radio>
                </a-radio-group>
              </a-form-item>
              <a-form-item label="图表主题">
                <xiri-form v-model="commonStyle.registerTheme" option="themeChoose" />
              </a-form-item>
              <a-form-item label="页面字体">
                <xiri-form v-model="commonStyle.fontFamily" option="fontChoose" />
              </a-form-item>
              <a-form-item label="封面图">
                <xiri-form v-model="visual.background_url" option="img" />
                <template #label>
                  <div>封面图</div>
                  <a-button size="small" variant="outline" @click="cutCover"> 截取封面 </a-button>
                </template>
              </a-form-item>
              <a-form-item label="屏幕水印" help="预览页才生效">
                <xiri-form v-model="commonStyle.watermarkShow" option="switch" />
              </a-form-item>
              <template v-if="commonStyle.watermarkShow">
                <a-form-item label="水印文字">
                  <xiri-form v-model="commonStyle.watermarkText" option="input" />
                  <span class="ml5" />
                  <a-button v-if="commonStyle.watermarkShow" variant="text" size="small"> 高级设置 </a-button>
                </a-form-item>
              </template>
            </a-form>
          </template>
        </div>
      </a-layout-sider>
    </a-layout>
  </a-layout>
</template>

<script setup>
// // 获取路由参数
import { useRoute, useRouter } from "vue-router"
import Global from "@/plugins/common/global.vue"
import { useFullscreen, useTitle } from "@vueuse/core"
import html2canvas from "html2canvas"
import { VueDraggable } from "vue-draggable-plus"
import canvasEdit from "./canvas.vue"
// //
import { useComponent, useVisual, useMenus, collapsed, onCollapse } from "@/hooks/userEditor.js"
const { handleSelect, rightClick } = useMenus()
import visualApi from "@/views/visual/api/visual.js"
import common from "@/api/common.js"

import Datasetting from "@/views/visual/screen/datasetting.vue"
import { Message } from "@arco-design/web-vue"
import { isDevMode } from "@/hooks/useUtil.js"
//
const route = useRoute()
const router = useRouter()
// // 获取屏幕id
const screenId = route.query.id
const optionValue = ref("one")
const optionComponentValue = ref("style")
const { commonStyle, visual } = useVisual()
//
const title = useTitle("未命名")
const {
  currentComponent,
  getComponent,
  componentList,
  selectComponent,
  sortComponent,
  groupManager,
  groupAlign,
  importCompoent
} = useComponent()
watch(currentComponent, (newVal) => {
  console.log(newVal)
  if (newVal.key) {
    optionValue.value = "one"
    optionComponentValue.value = "style"
  }
})
onMounted(async () => {
  if (!screenId) {
    visual.value.title = "未命名"
    return
  }
  // 获取屏幕详情
  const getVisual = await visualApi.read(screenId)
  // 正在加载
  await Message.loading("正在加载")
  visual.value = getVisual.data
  title.value = getVisual.data.title
  const res = await visualApi.getVisualConfig({ id: screenId })
  if (!res.data.config_json) return
  const config_json = JSON.parse(res.data.config_json)
  commonStyle.value = { ...commonStyle.value, ...config_json?.detail }
  await getComponent(config_json.component)
})

// 预览项目
const previewVisual = () => {
  const { toggle } = useFullscreen(canvasEditRef.value.$refs.container)
  toggle()
}
// 保存项目
const saveVisual = async () => {
  Message.loading("正在保存")
  // 校验是否有标题
  if (!visual.value.title) {
    await Message.error({
      content: "请填写标题"
    })
    return
  }
  const params = {
    detail: commonStyle.value,
    component: componentList.value
  }
  const newvisual = await visualApi.saveVisualData(visual.value)
  if (screenId > 0) {
    params.id = screenId
  } else {
    params.id = newvisual.data.id
  }
  params.config_json = JSON.stringify(params)

  const res = await visualApi.save(params)
  // 提示保存成功
  await Message.success({
    content: "保存成功",
    duration: 1000,
    onClose: () => {
      // 当前页面带参数刷新
      router.replace({
        path: "/visualEditor",
        query: {
          id: res.data.id
        }
      })
      // 重新加载页面
      setTimeout(() => {
        window.location.reload()
      })
    }
  })
}

// 查看结构
const viewStructure = () => {
  console.log(componentList.value)
}

// 截取封面
const canvasEditRef = ref(null)
const cutCover = () => {
  // 获取ref里的id是container的dom
  const dom = canvasEditRef.value.$refs.container
  html2canvas(dom, {
    useCORS: true
  }).then(function (canvas) {
    // 生成base64图片数据
    const dataUrl = canvas.toDataURL("image/jpeg", 1.0)
    const arr = dataUrl.split(",")
    const mime = arr[0].match(/:(.*?);/)[1]
    const bstr = atob(arr[1])
    let n = bstr.length
    const u8arr = new Uint8Array(n)
    while (n--) {
      u8arr[n] = bstr.charCodeAt(n)
    }
    const obj = new File([u8arr], "cover.jpg", { type: mime })
    const param = new FormData()
    param.append("file", obj)
    common.uploadImage(param).then((res) => {
      visual.value.background_url = res.data.url
    })
  })
}

const importJson = async () => {
  // 选择文件
  const input = document.createElement("input")
  input.type = "file"
  input.accept = ".json, .jihebi"
  input.click()
  input.onchange = () => {
    const file = input.files[0]
    const reader = new FileReader()
    reader.readAsText(file)
    reader.onload = async () => {
      const { bigdataForm, chartList } = JSON.parse(reader.result)
      const content = JSON.parse(bigdataForm.content)
      visual.value.title = bigdataForm.title
      const imageData = await common.saveNetWorkImage({ url: "https://suxuan.platomix.net" + content.bgImg })
      commonStyle.value.backgroundImage = imageData.data.url
      console.log(chartList)
      for (const item of chartList) {
        const olditem = g.Copy(item)
        const data = {}
        if (olditem.site.bgBackgroundSrc) {
          const imageData = await common.saveNetWorkImage({
            url: "https://suxuan.platomix.net" + olditem.site.bgBackgroundSrc
          })
          olditem.site.backgroundImage = "http://datav.mtgshenghuo.com" + imageData.data.url
        }
        if (olditem.name === "new-text") {
          data.name = "bi-text"
          data.title = olditem.title
          data.site = olditem.site
          data.option = olditem.option
          data.option.richText = false
          importCompoent(data)
        }
        if (olditem.name === "new-edit") {
          data.name = "bi-text"
          data.title = olditem.title
          data.site = olditem.site
          data.option = olditem.option
          data.option.richText = true
          importCompoent(data)
        }
        if (olditem.name === "new-img") {
          data.name = "bi-img"
          data.title = olditem.title
          data.site = olditem.site
          data.option = olditem.option
          importCompoent(data)
        }
      }
    }
  }
}
</script>

<style scoped lang="less">
.editor {
  height: 100%;
  background-color: var(--color-bg-white);

  .header {
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
    display: flex;
    justify-content: space-between;
    padding: 0 10px;
    align-items: center;
    box-sizing: border-box;
    border-bottom: 1px solid var(--color-neutral-4);
    height: 39px;
  }

  &-content {
    height: calc(100% - 46px);
    display: flex;
    overflow: hidden;

    .layer {
      width: 160px;
      height: 100%;
      border-right: 1px solid var(--color-neutral-4);
      -webkit-user-select: none;
      -moz-user-select: none;
      user-select: none;

      .header {
        display: flex;
        justify-content: space-between;
        border-bottom: 1px solid var(--color-neutral-4);
      }
      &-tool {
        display: flex;
        justify-content: space-between;
        border-bottom: 1px solid var(--color-neutral-4);
        padding: 5px 0;
      }
      &-list {
        display: flex;
        flex-direction: column;
        .layer-item {
          width: 100%;
          text-align: left;
          padding: 10px;
          box-sizing: border-box;
          cursor: move;
          border-bottom: 1px solid var(--color-neutral-4);
          display: flex;
          align-items: center;
          justify-content: space-between;
          .tool {
            display: flex;
            justify-content: right;
            gap: 8px;
            & > span {
              cursor: pointer;
              font-size: 12px;
            }
          }
          &:hover {
            background-color: var(--color-secondary);
          }

          // 选中状态
          &.active {
            background-color: var(--color-secondary);
          }
        }
      }
    }

    .layout {
      flex: 1 auto;
      width: calc(100% - 520px);
      overflow: hidden;
      height: 100%;
    }

    .option {
      border-left: 1px solid var(--color-neutral-4);
      height: 100%;

      &-header {
        text-align: center;
        height: 39px;
        -webkit-user-select: none;
        -moz-user-select: none;
        user-select: none;
        display: flex;
        justify-content: space-around;
        padding: 0 10px;
        align-items: center;
        box-sizing: border-box;
        border-bottom: 1px solid var(--color-neutral-4);
      }

      &-option {
        height: calc(100% - 42px);
        overflow: hidden;
        padding: 5px 0;
        box-sizing: border-box;
      }
      :deep(.arco-tabs-content) {
        overflow-y: auto;
        height: 90vh;
        padding: 0 5px 0 5px;
      }
    }
  }
}
</style>
